//
//  WBStatusListViewModel.swift
//  SinaWebo
//
//  Created by 亚杏 on 2017/5/17.
//  Copyright © 2017年 oms. All rights reserved.
//

import Foundation
import SDWebImage

//上拉最大次数
private let maxPullupTryTimes = 3
//微博数据列表视图模型
/** 父类的选择：
 - 如果类需要使用KVC，或者字典模型框架设置对象值，类就需要继承自NSObject
 - 如果类只是包装一些代码逻辑，写了一些函数 ，可以不用任何父类，更加轻量级
 - 如果用OC写，全部继承自NSObject
 
 使命： 负责微博的数据处理
 */
class WBStatusListViewModel {

    lazy var statusList = [WBStatusViewModel]() //微博模型数组，懒加载
    //上拉刷新错误次数
    private var pullupErrorTimes = 0

    //pullup，是否上拉
    func loadStatus(pullup:Bool, completion: @escaping (_ isSuccess: Bool, _ shouldRefresh: Bool) -> ()) {

        //since_id 下拉，刷新数据，取出数组中第一条微博的id
        let since_id = pullup ? 0 :(statusList.first?.status.id ?? 0)
        let max_id = !pullup ? 0 : (statusList.last?.status.id ?? 0)


        //如果上拉刷新 ，检查刷新错误
        if pullup && pullupErrorTimes > maxPullupTryTimes {
            completion(true,false)
            return
        }
        // 让数据访问层加载数据
        WBStatusListDAL.loadStatus(since_id: since_id, max_id: max_id) { (list, isSuccess) in

      //  }
//        WBNetworkManager.shared.statusList(since_id: since_id, max_id: max_id) { (list:[[String : AnyObject]]?, isSuccess: Bool) in

            //0. 判断网络请求是否成功
            if !isSuccess{
                completion(false, false)
                return
            }

            //1 字典转模型
            //1> 定义结果可变数组
            var array = [WBStatusViewModel]()

            //2> 遍历返回的字典数组，字典转模型
            for dict in list ?? [] {

                //a> 创建微博模型,如果创建失败，继续遍历
                guard let model = WBStatus.yy_model(with: dict) else{
                    continue
                }
                //b> 将 视图模型 添加到array
                array.append(WBStatusViewModel(model:model))
            }

            print("刷新了\(array.count)条数据\(array)")
            //2 拼接数据
            if pullup{
                //上拉刷新，拼接到末尾
                self.statusList += array
            }else{
                //下拉刷新 ，应该将数组插入原数据前
                self.statusList = array + self.statusList
            }

            //判断上拉刷新数据量
            if pullup && array.count == 0{
                self.pullupErrorTimes += 1
                completion(isSuccess,false)
            }else{
            //3 完成回调
                self.cacheSingleImage(list: array, finished: completion)
            }
        }
    }


    /// 缓存本次下载微博数据数组中的单张图像
    /// 应该缓存完单张图像，并且修改配图的大小后再回调，才能保证表格比例显示单张图像
    /// - Parameter list: 本次下载的视图模型数组
    private func cacheSingleImage(list: [WBStatusViewModel], finished: @escaping (_ isSuccess: Bool, _ shouldRefresh: Bool) -> ()) {

        //调度组
        let group = DispatchGroup()

        //记录数据长度
        var length = 0
        //1.遍历数组，查找有单张图像的，进行缓存
        for vm in list {
            //1> 判断图像数量
            if vm.picURLs?.count != 1 {
                continue
            }

            //2> 获取单张图像地址
           guard let pic = vm.picURLs?[0].thumbnail_pic,
            let url = URL(string: pic) else{
                continue
            }

            // A> 入组
            group.enter()


//            print("要缓存的 URL 是 \(url)")

            // 3> 下载图像
            //1）downloadImage 是 SDWebImage 的核心方法，
            //2）图像下载完成后会自动保存在沙盒中，文件路径是url的md5
            //3）如果沙盒中已经存在缓存的图像，后续使用sd_set 通过URL加载图像，都会加载本地沙盒中图像
            //4）不会发起网络请求，同时，回调方法同样会调用
            //5) 方法还是同样的方法，调用还是同样的调用，不过内部不会再次发起网络请求
            //*** 注意点：如果要缓存的图像累计很大，找后台要接口
            SDWebImageManager.shared().downloadImage(with: url, options: [], progress: nil, completed: { (image, _ , _, _, _) in

                //将图像转换成二进制数据
                if let image = image,
                   let data = UIImagePNGRepresentation(image){
                    length += data.count

                    //图像缓存成功，更新配图视图
                    vm.updateSinglePicViewSize(image: image)
                }

//                print("缓存的图像是 \(image) 长度\(length)")
                //出组
                group.leave()
            })
        }

        //监听调度组情况
        group.notify(queue: DispatchQueue.main) { 
            print("图像缓存完成\(length/1024)K")
            //有数据的回调
            finished(true,true)
        }

    }
}



